#include"ProcessPoll.hpp"
#include<iostream>
#include<vector>
#include<string>
#include<sys/stat.h>
#include<sys/wait.h>
#include<cstdlib>
#include<unistd.h>
#include<ctime>


std::vector<task_t> tasks;

#define N 5;
#define NUM 5  //设置进程个数

//进程描述
class channel
{
public:
    //构造函数
    channel(int cmdfd,pid_t slaverid,const std::string & processname)
        :_cmdfd(cmdfd)
        ,_slaverid(slaverid)
        ,_processname(processname)
    {}

//private:
    int _cmdfd;                 //发送任务的文件描述符
    pid_t _slaverid;            //子进程的PID
    std::string _processname;   //子进程的名字
};


void Slaver()
{
    while(true)
    {
        int cmdcode = 0;
        ssize_t n = read(0,&cmdcode,sizeof(int));
        if(n == sizeof(int))
        {
            //执行cmdcode对应的任务列表
            std::cout <<"slaver say@ get a command: "<< getpid() << " : cmdcode: " <<  cmdcode << std::endl;
            if(cmdcode >= 0 && cmdcode < tasks.size()) tasks[cmdcode]();
        }
        else if(n == 0)
        {
            break;
        }

    }
}
void CtrlSalver(const std::vector<channel>& channels)
{
    int cnt = N;
    while(cnt--)
    {
        //int select;
        //std::cout<<"Please Enter@";
        //std::cin >> select;

        //选择任务
        int cmdcode  = rand()% tasks.size();
        //选择进程
        int whichpro = rand()% channels.size();

        std::cout << "father say: " << " cmdcode: " <<
            cmdcode << " already sendto " << channels[whichpro]._slaverid << " process name: " 
                << channels[whichpro]._processname << std::endl;

        write(channels[whichpro]._cmdfd,&cmdcode ,sizeof(int));
        sleep(1);
    }
}

void InitProcessPoll(std::vector<channel>* channels)
{
    for(int i = 0; i < NUM ; i++)
    {
        int pipefd[2]; // 在函数里的临时空间
        int n = pipe(pipefd);
        
        //创建子进程
        pid_t id = fork();
        if(id == 0)
        {
            close(pipefd[1]);
            dup2(pipefd[0],0);  //重定向到stdin
            close(pipefd[0]);
            Slaver();

            exit(0);
        }
        //fatherPeocessPoll
        close(pipefd[0]);   //关闭读端        
        //构建数组
        std::string name = "chlid-" + std::to_string(i);
        channels->push_back(channel(pipefd[1],id,name));
    }
}

void QuitProcess(const std::vector<channel> &channels)
{
    for(const auto &c : channels) close(c._cmdfd);
    // sleep(5);
    for(const auto &c : channels) waitpid(c._slaverid, nullptr, 0);
    // sleep(5);
}


void test(const std::vector<channel>& channels)
{
    for(int i = 0 ; i < NUM; i++)
    {
        std::cout <<"fd:"<<channels[i]._cmdfd <<"child_PID: "<<channels[i]._slaverid
        <<"child_name: "<<channels[i]._processname<< std::endl;
    }
}



int main()
{
    LoadTask(&tasks);
    srand(time(nullptr));
    
    std::vector<channel> channels;

    //初始化
    InitProcessPoll(&channels);
    //测试
    //test(channels);

    //控制子进程
    CtrlSalver(channels);

    //退出进程
    QuitProcess(channels);
    return 0;

}
